<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2.3.1-框架要做到良好的 Tree-Shaking</title>
</head>
<body>
    
</body>
    <script>
        /**
         * Tree-Shaking 指的就是消除那些永远不会被执行的代码，也就是排除 dead code
         * - 想要实现 Tree-Shaking，必须满足一个条件，即模块必须是 ESM（ES Module）， 
         *   因为 Tree-Shaking 依赖 ESM 的静态结构
         * - Tree-Shaking 中的第二个关键点 —— 副作用
         * --  如果一个函数调用会产生副作用，那么就不能将其移除
         * 
         * 注释代码ex: /*#__PURE__*\/ foo() ---(这里 ‘\’ 是防止报错)
         * - 其作用就是告诉 rollup.js，
         *   对于 foo 函数的调用不会产生副作用，你可以放心地对其进行 Tree-Shaking
         * - 通常产生副作用的代码都是模块内函数的顶级调用, 
         *   基本都是在一些顶级调用的函数上使用
         * - 该注释不仅仅作用于函数，它可以应用于任何语句上
         * - 该注释也不是只有 rollup.js 才能识别，webpack 以及压缩工具（如 terser）都能识别它
         * 
         * 什么是副作用？
         * - 副作用就是，当调用函数的时候会对外部产生影响，例如修改了全局变量
         * - Proxy 创建的代理对象，那么当我们读取对象属性时，
         *   就会触发代理对象的 get 夹子（trap），在 get 夹子中是可能产生副作用的
         * - 到底会不会产生副作用，只有代码真正运行的时候才能知道，JavaScript 本身是动态语言
        */

        // Tree-Shaking 如何工作 --------------------------------------------
        // input.js
        import { foo } from './utils.js'
        foo()

        // utils.js
        export function foo(obj) {
            obj && obj.foo
        }
        export function bar(obj) {
            obj && obj.bar
        }

        // 执行如下命令进行构建
        // npx rollup input.js -f esm -o bundle.js

        /**
         * bundle.js
         * 没有使用 bar 函数，因此它作为 dead code 被删除了
         * */ 
        function foo(obj) {
            obj && obj.foo
        }
        foo();
        // Tree-Shaking 如何工作 --------------------------------------------

        /**
         * 什么是顶级调用呢？
         * */ 
        foo() // 顶级调用

        function bar() {
            foo() // 函数内调用
        }

    </script>
</html>